/**
Contains code for doing a simple flyout in a widget. The flyout is configured with a template, and then passed any arbitrary data to render using that template.
More complex implementations are possible (eg, showing subordinate widgets in the flyout, or with animations) but we're not addressing that here.

Note that the argument to show() is the data to render using the template. It is passed into insertTemplate(), so those rules are followed.
Basically whatever you pass in becomes the ${Data} token in the template
*/

/**
Constructor
Arguments object should have:
{  
buzzObj, //owner BuzzObj
mainContainerId : "buzzContainerId", //ID of element to position flyout next to
flyoutTemplate : template, //the full template string, NOT an element ID or a variable name
flyoutMargin : 10, //number of pixels to offset the flyout
direction : "right", //optional, "left" or "right", default is "right"
*/
function NGSimpleFlyout(args){
	this.mainElem = document.getElementById(args.mainContainerId);
	this.BuzzObj = args.buzzObj;
	this.flyoutTemplate = args.flyoutTemplate || "";
	this.flyoutMargin = args.flyoutMargin;	
		
	if(args.direction){
		switch(args.direction.toLowerCase()){
			case "left":
				this.direction = "left";
				break;
			
			case "right":
			default:
				this.direction = "right";
				break;
		}
	}
	
	//Track whether the flyout is currently visible
	this.flyoutOpen = false;
	
	//Object to hold event handlers
	this.events = {
		//these are the available events, name followed by (arguments)
		//preRender (dataObj)
		//preOpen   (dataObj, flyoutElem)   //note this will still fire if the flyout was already open for another post
		//postOpen  (dataObj, flyoutElem)  //note this will still fire if the flyout was already open for another post
		//preClose  (flyoutElem)
		//postClose (flyoutElem)
	};

	this._setupFlyout();
	
};

NGSimpleFlyout.prototype = {
	/**
	* Public function to show the flyout for a post
	*/
	show: function(dataObj) {
		this._renderFlyout(dataObj);

		if (!this.isFlyoutOpen) {
			this._open(dataObj);
		}
	},

	/**
	* Public function to hide the flyout
	*/
	hide: function() {
		this._fireEvent("preClose", [this.popupElem]);

		ng_removeBackgroundIframe(this.popupElem);

		this.popupElem.style.display = "none";
		this.flyoutOpen = false;

		this._fireEvent("postClose", [this.popupElem]);
	},

	/**
	* Public function to bind an event handler
	*/
	addEvent: function(eventName, handler) {
		var handlers = this.events[eventName] || [];

		if (handler.apply) {
			handlers.push(handler);
		} else if (handler.substring) { //looks like a string
			handlers.push(new Function([/* no args */], handler));
		}

		this.events[eventName] = handlers;
	},


	/**
	* Internal function to execute all the handlers for an event
	*/
	_fireEvent: function(eventName, args) {
		var handlers = this.events[eventName];

		if (handlers) {
			for (var i = 0; i < handlers.length; i++) {
				try {
					handlers[i].apply(this, args);
				} catch (e) {
					ng_debug("Error executing flyout event handler " + eventName, e.message);
				}
			}
		}
	},

	/**
	* Internal function to perform the mechanics of showing the flyout box
	*/
	_open: function(dataObj) {
		var popup = this.popupElem;
		var s = popup.style;

		this._fireEvent("preOpen", [dataObj, popup]);

		if (this.direction == "left") {
			s.display = "block";
			var fWidth = (popup.clientWidth || popup.offsetWidth);
			s.left = (-1 * (fWidth + this.flyoutMargin + 0)) + "px";
		}
		else {
			var mWidth = (this.mainElem.clientWidth || this.mainElem.offsetWidth);
			s.left = (mWidth + this.flyoutMargin + 0) + "px";
			s.display = "block";
		}

		ng_addBackgroundIframe(popup);

		this.flyoutOpen = true;

		this._fireEvent("postOpen", [dataObj, popup]);
	},

	/**
	* internal function to render out the post HTML
	*/
	_renderFlyout: function(dataObj) {
		this._fireEvent("preRender", [dataObj]);

		this.BuzzObj.insertTemplate(this.flyoutTemplate, this.popupElem.id, dataObj);
	},

	_setupFlyout: function() {
		var container = document.createElement("DIV");
		container.style.display = "block";
		container.style.position = "relative";
		container.style.height = "0";

		var popup = document.createElement("DIV");
		popup.style.position = "absolute";
		popup.style.zIndex = "1000";
		popup.style.display = "none";
		popup.style.padding = "0px";
		popup.id = "ngFlyoutPopup_" + Math.floor(Math.random() * 1000000000);

		container.appendChild(popup);

		this.popupElem = popup;

		var mainElem = this.mainElem;
		if (mainElem.childNodes && mainElem.childNodes.length > 0) {
			mainElem.insertBefore(container, mainElem.childNodes[0]);
		} else {
			mainElem.appendChild(container);
		}
	}
};

